<template>
  <div class="relation-wrapper">
    <div class="relation-block" v-if="hasRelation">
      <i class="el-icon-refresh" @click="handleSwitch()"></i>
      <span>{{ relation }}</span>
    </div>
    <div class="relation-wrapper__main">
      <template v-for="(item, index) in conditions">
        <query-condition
          :value="item"
          :active="
            index === activeIndex &&
            level === activeLevel &&
            levelId === activeLevelId
          "
          v-if="isCondition(item)"
          :key="index"
          :level-id="levelId"
          :isLog="isLog"
          :relations="relations"
          @add="handleAddCondition(item, index)"
          @delete="(level) => handlerDeleteCondition(item, index, level)"
          @input="(val) => handleInput(val, index)"
        />
        <relation-wrapper
          v-if="!isCondition(item)"
          ref="wrapper"
          :relations="item"
          :key="index"
          :level="level + 1"
          :level-id="getLevelId(index)"
          :active-index="activeIndex"
          :active-level="activeLevel"
          :active-level-id="activeLevelId"
          :isLog="isLog"
          @activate="
            (level, levelId, index) => $emit('activate', level, levelId, index)
          "
          @beforeActivate="$emit('beforeActivate')"
          @getRelations="getRelations"
        ></relation-wrapper>
      </template>
    </div>
  </div>
</template>

<script>
import QueryCondition from "./QueryCondition.vue";
import { mapState } from "vuex";
let id = 1;
const relationLocaleMap = {
  OR: "或",
  AND: "且",
};
export default {
  components: { QueryCondition },
  name: "RelationWrapper",
  componentName: "RelationWrapper",
  data() {
    return {
      typeList: [],
    };
  },
  mounted() {
    this.typeList = this.isLog ? this.typeMapList : this.typeSearchList;
  },
  props: {
    relations: {
      type: Array,
      default: () => ["", [{ fieldName: "", operator: "EQ", value: "" }]],
    },
    level: {
      type: Number,
      default: 0,
    },
    levelId: {
      type: String,
      default: "",
    },
    activeLevel: {
      type: Number,
      default: -1,
    },
    activeIndex: {
      type: Number,
      default: -1,
    },
    activeLevelId: {
      type: String,
    },
    isLog: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    ...mapState("log", ["typeMapList"]),
    ...mapState("rule", ["typeSearchList"]),
    hasRelation() {
      return (
        this.relations.length > 0 &&
        typeof this.relations[0] === "string" &&
        this.relations[1] &&
        this.relations[1].length > 1
      );
    },
    relation() {
      return (this.hasRelation && relationLocaleMap[this.relations[0]]) || "";
    },
    conditions() {
      if (this.relations.length === 0) {
        return [];
      }
      // 判断是否是元组，是元组用第二个字段递归渲染
      if (typeof this.relations[0] === "string") {
        return this.relations[1] || [];
      }
      // 判断是否是对象，是则组装成数组，兼容单个对象的场景
      if (
        Object.prototype.toString.call(this.relations) === "[object Object]"
      ) {
        return [this.relations];
      }
      return this.relations;
    },
  },
  methods: {
    getRelations(index) {
      if (
        Object.prototype.toString.call(this.relations) === "[object Object]"
      ) {
        return;
      }
      if (this.relations[1] && this.relations[1].length > 0) {
        let level = 0;
        let toDelIndex = -1;
        for (let i = 0; i < this.relations[1].length; i++) {
          const item = this.relations[1][i];
          if (Array.isArray(item)) {
            if (typeof item[0] === "string" && item[1].length === 0) {
              level++;
            } else if (typeof item[0] === "string" && item[1].length === 1) {
              this.relations[1][i] = item[1][0];
              break;
            }
          }
          if (level === index) {
            toDelIndex = index;
            break;
          }
        }
        if (toDelIndex >= 0) {
          this.relations[1].splice(toDelIndex, 1);
        }
        if (this.relations[1].length <= 1) {
          this.$emit("getRelations", +this.levelId.split("_").slice(-1)[0]);
        }
      }
    },
    isCondition(item) {
      const isr = Object.prototype.toString.call(item) === "[object Object]";
      // console.log(isr);
      return isr;
    },
    getLevelId(index) {
      let levelIndex = 0;
      for (var i = 0; i <= index; i++) {
        if (!this.isCondition(this.conditions[i])) {
          levelIndex += 1;
        }
      }
      return this.levelId + "_" + levelIndex;
    },
    handlerDeleteCondition(item, index, level) {
      // TODO 从数组中移除此下标
      this.relations[1].splice(index, 1);
      if (this.relations[1].length <= 1) {
        this.$emit("getRelations", +this.levelId.split("_").slice(-1)[0]);
      }
      // console.log("===" + this.relations);
    },

    deleteUnhandledBeforeAdd() {
      if (
        this.activeLevelId &&
        this.levelId === this.activeLevelId &&
        this.level === this.activeLevel &&
        this.activeIndex >= 0
      ) {
        this.relations[1].splice(this.activeIndex, 1);
      }
      if (this.$refs.wrapper) {
        this.$refs.wrapper.forEach((item) => item.deleteUnhandledBeforeAdd());
      }
    },
    handleAddCondition(item, index) {
      // 一个或者当前高亮的点击不处理
      if (
        this.relations[1].length === 1 ||
        (this.activeLevel === this.level &&
          this.activeLevelId === this.levelId &&
          this.activeIndex === index)
      ) {
        return;
      }
      this.$emit("beforeActivate");
      if (
        this.activeLevelId &&
        this.levelId === this.activeLevelId &&
        this.level === this.activeLevel &&
        this.activeIndex >= 0
      ) {
        if (index >= this.activeIndex) {
          index -= 1;
        }
      }
      const itemId = id++;

      this.relations[1].splice(index + 1, 0, {
        fieldName: this.typeList[0].columnName,
        operator: this.isLog
          ? this.typeList[0].operatorList[0].paramValue
          : "EQ",
        value: "",
        id: itemId,
      });

      // this.deleteUnhandledBeforeAdd();
      const realIndex = this.relations[1].findIndex(
        (item) => item.id === itemId
      );
      this.$emit("activate", this.level, this.levelId, realIndex);
    },
    handleInput(val, index) {
      // console.log(val, index);
      this.$set(this.relations[1], index, {
        ...this.relations[1][index],
        ...val,
      });
    },

    createRelation(relation, oldRelations) {
      if (this.level === this.activeLevel && this.activeIndex > 0) {
        const items = this.relations[1].slice(
          this.activeIndex - 1,
          this.activeIndex + 1
        );
        const relationData = [relation, items];
        this.relations[1].splice(
          this.activeIndex - 1,
          items.length,
          relationData
        );
        // 清除高亮行
        this.$emit("activate", -1, "", -1);
      } else if (
        this.$refs.wrapper &&
        this.$refs.wrapper.length > 0 &&
        this.activeIndex > 0
      ) {
        this.$refs.wrapper.forEach((item) => item.createRelation(relation));
      } else {
        let fieldName = this.typeList[0].columnName;
        let operator = this.isLog
          ? this.typeList[0].operatorList[0].paramValue
          : "EQ";
        if (this.relations[1].length === 1) {
          this.$set(this.relations, 0, relation);
          if (relation === this.relations[0]) {
            this.relations[1].push({
              fieldName: fieldName,
              operator: operator,
              value: "",
            });
            return;
          }
          this.relations[1].push({
            fieldName: fieldName,
            operator: operator,
            value: "",
          });
        } else {
          if (relation === this.relations[0]) {
            this.relations[1].push({
              fieldName: fieldName,
              operator: operator,
              value: "",
            });
            return;
          }
          this.$set(this.relations, 0, relation);

          this.$set(this.relations, 1, [
            oldRelations,
            { fieldName: fieldName, operator: operator, value: "" },
          ]);
        }
      }
    },
    handleSwitch() {
      this.$set(this.relations, 0, this.relations[0] === "OR" ? "AND" : "OR");
    },
  },
};
</script>

<style lang="scss" scoped>
.relation-wrapper {
  display: flex;
  align-items: stretch;
  justify-content: flex-start;
  & >>> .relation-wrapper {
    border-left: none;
    border-right: none;
  }
  .relation-block {
    width: 35px;
    min-width: 35px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #dedede;
    border-right: 0;
    position: relative;
    &:hover {
      > .el-icon-refresh {
        opacity: 1;
      }
    }
  }
  .relation-wrapper__main {
    flex: 1;
    .relation-wrapper {
      border-left: none;
      border-right: none;
    }
  }

  .el-icon-refresh {
    opacity: 0;
    cursor: pointer;
    position: absolute;
    top: 20px;
    left: 50%;
    transform: translate3d(-50%, 0, 0);
  }
}
</style>
